﻿using System.Drawing;
using System.Drawing.Imaging;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Xml.Linq;
using BootstrapBlazor.Components;
using CardMaker.Library.Models;
using Console = System.Console;

namespace CardMaker.Library.Services;

public class SideImageStorage : ISideImageStorage {
    private const string type = "png";
    private readonly ICardTemplateStorage _cardTemplateStorage;
    private string path = "";
    private readonly string _sideImageBox = "SideImageBox";

    public Task InitializeAsync() {
        //确实创建了文件夹，但是与数据库不在一个位置，两个位置完全不同
        path = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder
                .LocalApplicationData), _sideImageBox);
        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);

        return Task.CompletedTask;
    }

    //可能存在bug的版本
    public async Task<IEnumerable<SideImage>> GetSideImagesAsync(int cardTemplateId) {
        var cardTemplate =
            await _cardTemplateStorage.GetCardTemplateAsync(cardTemplateId);
        var options = new JsonSerializerOptions {
            WriteIndented = true, //大小写区分
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping //解决中文乱码
        };
        var sideImages =
            JsonSerializer.Deserialize<List<SideImage>>(cardTemplate.SideImages,
                options);
        foreach (var s in sideImages)
            s.SideKeXuanImageBytes = GetImagesAsBytes(s.SideImageKeXuan, path);
        return sideImages;
    }

    public async Task SaveSideImageAsync(
        IEnumerable<SideImage> sideImages) {
        foreach (var item in sideImages) {
            await SaveSideImageAsync(item);
        }
    }

    public async Task SaveSideImageAsync(SideImage sideImage) {
        if ("" == path)
            return;
        //todo
        if (sideImage.SideImageKeXuan != null)
            for (var i = 0; i < sideImage.SideImageKeXuan.Count; i++) {
                var filePath = Path.Combine(path,
                    sideImage.SideImageKeXuan[i] + "." + type);
                if (File.Exists(filePath)) {
                    //todo 已经存在提示覆盖
                    File.Delete(filePath);
                }
                try
                {
                    await using var imageFileStream =
                        new FileStream(filePath, FileMode.Create);
                    await imageFileStream.WriteAsync(
                        sideImage.SideKeXuanImageBytes[i], 0,
                        sideImage.SideKeXuanImageBytes[i].Length);
                    imageFileStream.Close();
                }
                catch (IOException e)
                {
                    Console.WriteLine(e);
                    throw;
                }
                
            }
    }


    public List<byte[]?> GetImagesAsBytes(List<string> fileNames,
        string folderpath) {
        var imageBytesList = new List<byte[]?>();

        foreach (var fileName in fileNames) {
            // 构造完整的文件路径
            var filePath = Path.Combine(folderpath, fileName + "." + type);

            // 检查文件是否存在
            if (File.Exists(filePath)) {
                // 将图片转换为二进制数据
                var imageData = ImageToByteArray(filePath);
                imageBytesList.Add(imageData);
            }
        }

        return imageBytesList;
    }

    //GetSideImagesAsync 原方法在副图找不到文件时，list下标会与可选项名出现的不对应的情况，在下方给出修改的版本
    public async Task<IList<SideImage>> GetSideImagesAsync(
        CardTemplate cardTemplate)
    {
        var options = new JsonSerializerOptions
        {
            WriteIndented = true, //大小写区分
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping //解决中文乱码
        };
        var sideImages =
            JsonSerializer.Deserialize<List<SideImage>>(cardTemplate.SideImages,
                options); //反序列化
        if (sideImages.Count==0) {
            return new List<SideImage>();
        }
        var sideImagesCopy = new List<SideImage>(sideImages); //复制一份集合
        for (int i = 0; i < sideImagesCopy.Count; i++) //使用非增强循环，因为需要修改内容
        {
            var s = sideImagesCopy[i];
            if (s.Equals(null))
                return null;
            
            var sideImageKeXuanCopy = new List<string>(s.SideImageKeXuan); //复制一份集合
            for (int j = 0; j < sideImageKeXuanCopy.Count; j++) //使用 for 循环
            {
                var imageMemoryStream = new MemoryStream();
                var kexuan = sideImageKeXuanCopy[j];
                var filePath = Path.Combine(path, kexuan + "." + type);
                try {
                    var imageFileStream = new FileStream(filePath, FileMode.Open);
                    await imageFileStream.CopyToAsync(
                        imageMemoryStream); //文件流转换到内存流
                    await s.InputStandKeXuan(kexuan,
                        imageMemoryStream
                            .ToArray()); //使用增强的AddKeXuan方法，使得byte数组中的图片信息和可选项数组中的下标严格一致
                    imageFileStream.Close();
                    imageMemoryStream.Close();
                } catch (IOException e) {
                    //todo
                    Console.WriteLine(e);
                    throw;
                }
            }
        }
        return sideImagesCopy;
    }


    //配合重写的get方法
    private Task<byte[]?> GetImageAsBytes(string name) //通过被严格命名的kexuan 名来找到相应的文件读取
    {
        name ??= "default";
        var filePath = Path.Combine(path, name + "." + type);
        // 检查文件是否存在
        if (File.Exists(filePath)) {
            var imageData = ImageToByteArray(filePath);
            return Task.FromResult(imageData);
        }

        //todo 添加一个嵌入图片 用来展示出现错误的图片
        return Task.FromResult<byte[]?>(null); //不存在返空
    }

    //不可使用
    public byte[]? ImageToByteArray(string imagePath) {
        // 从文件读取图片
        var image = Image.FromFile(imagePath);

        // 将图片转换为二进制数据
        using (var ms = new MemoryStream()) {
            image.Save(ms, ImageFormat.Png); // 使用 Png 格式
            return ms.ToArray();
        }
    }
}